import 'package:chatgreat/bloc/account_bloc.dart';

import 'package:chatgreat/bloc/free_count_bloc.dart';
import 'package:chatgreat/bloc/gallery_bloc.dart';

import 'package:chatgreat/bloc/version_bloc.dart';
import 'package:chatgreat/helper/cache.dart';
import 'package:chatgreat/helper/logger.dart';
import 'package:chatgreat/helper/model.dart';
import 'package:chatgreat/helper/model_resolver.dart';
import 'package:chatgreat/helper/platform.dart';
import 'package:chatgreat/helper/purchase_pay.dart';
import 'package:chatgreat/lang/lang.dart';
import 'package:chatgreat/data/migrate.dart';
import 'package:chatgreat/page/component/chat/message_state_manager.dart';
import 'package:chatgreat/repo/api_server.dart';
import 'package:chatgreat/repo/cache_repo.dart';
import 'package:chatgreat/repo/creative_island_repo.dart';
import 'package:chatgreat/repo/data/cache_data.dart';
import 'package:chatgreat/repo/data/chat_history.dart';
import 'package:chatgreat/repo/data/creative_island_data.dart';
import 'package:chatgreat/repo/deepai_repo.dart';
import 'package:chatgreat/repo/stabilityai_repo.dart';
import 'package:chatgreat/router.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:chatgreat/helper/constant.dart';
import 'package:chatgreat/page/component/theme/custom_theme.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_localization/flutter_localization.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:go_router/go_router.dart';

import 'package:provider/provider.dart';
import 'package:chatgreat/bloc/bloc_manager.dart';
import 'package:chatgreat/bloc/chat_message_bloc.dart';
import 'package:chatgreat/bloc/room_bloc.dart';

import 'package:chatgreat/repo/data/chat_message_data.dart';
import 'package:chatgreat/repo/chat_message_repo.dart';
import 'package:chatgreat/repo/data/room_data.dart';
import 'package:chatgreat/repo/openai_repo.dart';
import 'package:chatgreat/repo/data/settings_data.dart';
import 'package:chatgreat/repo/settings_repo.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'helper/AppUtil.dart';
import 'helper/path.dart';
import 'page/component/theme/theme.dart';
import 'package:chatgreat/helper/http.dart' as httpx;
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:media_kit/media_kit.dart';

void main() async {
  WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);

  MediaKit.ensureInitialized();
  httpx.HttpClient.init();
  SharedPreferences.getInstance();

  // 初始化路径，获取到系统相关的文档、缓存目录
  await PathHelper().init();

  FlutterError.onError = (FlutterErrorDetails details) {
    if (details.library == 'rendering library' ||
        details.library == 'image resource service') {
      return;
    }

    Logger.instance.e(
      details.summary,
      error: details.exception,
      stackTrace: details.stack,
    );
    print(details.stack);
  };

  // if (kIsWeb) {
  //   databaseFactory = databaseFactoryFfiWeb;
  // } else {
  //   if (PlatformTool.isWindows() ||
  //       PlatformTool.isLinux() ||
  //       PlatformTool.isMacOS()) {
  //     sqfliteFfiInit();
  //     databaseFactory = databaseFactoryFfi;
  //     var path = absolute(join(PathHelper().getHomePath, 'databases'));
  //     databaseFactory.setDatabasesPath(path);
  //   }
  // }

  // 数据库连接
  final db = await databaseFactory.openDatabase(
    'system.db',
    options: OpenDatabaseOptions(
      version: databaseVersion,
      onUpgrade: (db, oldVersion, newVersion) async {
        try {
          await migrate(db, oldVersion, newVersion);
        } catch (e) {
          Logger.instance.e('数据库升级失败', error: e);
        }
      },
      onCreate: initDatabase,
      onOpen: (db) {
        Logger.instance.i('数据库存储路径：${db.path}');
      },
    ),
  );

  // 加载配置
  final settingProvider = SettingDataProvider(db);
  await settingProvider.loadSettings();

  // 创建数据仓库
  final settingRepo = SettingRepository(settingProvider);
  final openAIRepo = OpenAIRepository(settingProvider);
  final deepAIRepo = DeepAIRepository(settingProvider);
  final stabilityAIRepo = StabilityAIRepository(settingProvider);
  final cacheRepo = CacheRepository(CacheDataProvider(db));

  final chatMsgRepo = ChatMessageRepository(
    RoomDataProvider(db),
    ChatMessageDataProvider(db),
    ChatHistoryProvider(db),
  );

  final creativeIslandRepo =
      CreativeIslandRepository(CreativeIslandDataProvider(db));

  // 聊天状态加载器
  final stateManager = MessageStateManager(cacheRepo);

  // 初始化聊天实现解析器
  ModelResolver.instance.init(
    openAIRepo: openAIRepo,
    deepAIRepo: deepAIRepo,
    stabilityAIRepo: stabilityAIRepo,
  );

  APIServer().init(settingRepo);
  ModelAggregate.init(settingRepo);
  Cache().init(settingRepo, cacheRepo);
  PurchasePay();

  // 初始化聊天室 Bloc 管理器
  final m = ChatBlocManager();
  m.init((roomId, {chatHistoryId}) {
    return ChatMessageBloc(
      roomId,
      chatHistoryId: chatHistoryId,
      chatMsgRepo: chatMsgRepo,
      settingRepo: settingRepo,
    );
  });

  runApp(MyApp(
    settingRepo: settingRepo,
    chatMsgRepo: chatMsgRepo,
    openAIRepo: openAIRepo,
    cacheRepo: cacheRepo,
    creativeIslandRepo: creativeIslandRepo,
    messageStateManager: stateManager,
  ));
  configLoading();
  ///-------默认设置状态栏文字icon为白色-------
  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
}

// 设置loading，其他配置见官方文档
void configLoading() {
  EasyLoading.instance
    ..displayDuration = const Duration(milliseconds: 2000)  // 加载时间
    ..indicatorType = EasyLoadingIndicatorType.wave  // 加载类型
    ..loadingStyle = EasyLoadingStyle.light  // 加载样式
    ..indicatorSize = 45.0   // 大小
    ..maskType = EasyLoadingMaskType.clear // 遮罩
    ..userInteractions = true  // 使用单例模式
    ..dismissOnTap = false;  // 指示器结束的点击时间
}

class MyApp extends StatefulWidget {
  // 页面路由
  late final GoRouter _router;

  // Bloc
  late final RoomBloc chatRoomBloc;
  late final GalleryBloc galleryBloc;
  late final AccountBloc accountBloc;
  late final VersionBloc versionBloc;
  late final FreeCountBloc freeCountBloc;

  final _rootNavigatorKey = GlobalKey<NavigatorState>();
  final _shellNavigatorKey = GlobalKey<NavigatorState>();
  final FlutterLocalization localization = FlutterLocalization.instance;
  final MessageStateManager messageStateManager;

  MyApp({
    super.key,
    required this.settingRepo,
    required this.chatMsgRepo,
    required this.openAIRepo,
    required this.cacheRepo,
    required this.creativeIslandRepo,
    required this.messageStateManager,
  }) {
    chatRoomBloc =
        RoomBloc(chatMsgRepo: chatMsgRepo, stateManager: messageStateManager);
    accountBloc = AccountBloc(settingRepo);
    versionBloc = VersionBloc();
    galleryBloc = GalleryBloc();
    freeCountBloc = FreeCountBloc();

    var apiServerToken = settingRepo.get(settingAPIServerToken);
    var usingGuestMode = settingRepo.boolDefault(settingUsingGuestMode, false);

    final openAISelfHosted =
        settingRepo.boolDefault(settingOpenAISelfHosted, false);
    final deepAISelfHosted =
        settingRepo.boolDefault(settingDeepAISelfHosted, false);
    final stabilityAISelfHosted =
        settingRepo.boolDefault(settingStabilityAISelfHosted, false);

    AppUtil().rootNavigatorKey = _rootNavigatorKey;
    _router = getRouter(
        settingRepo,
        creativeIslandRepo,
        chatMsgRepo,
        messageStateManager,
        _shellNavigatorKey,
        _rootNavigatorKey,
        freeCountBloc,
        chatRoomBloc,
        galleryBloc,
        accountBloc,
        versionBloc);
  }

  final SettingRepository settingRepo;
  final ChatMessageRepository chatMsgRepo;
  final OpenAIRepository openAIRepo;
  final CacheRepository cacheRepo;
  final CreativeIslandRepository creativeIslandRepo;

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    // 初始化多语言
    // final defaultLanguage = resolveSystemLanguage(PlatformTool.localeName());
    // var initLanguage =
    //     widget.settingRepo.stringDefault(settingLanguage, defaultLanguage);

    widget.localization.init(
      mapLocales: [
        const MapLocale('zh', AppLocale.zh),
        const MapLocale('zh-CHS', AppLocale.zh),
        // const MapLocale('en', AppLocale.en),
      ],
      // initLanguageCode: initLanguage == '' ? defaultLanguage : initLanguage,
      initLanguageCode: 'zh-CHS',
    );

    widget.localization.onTranslatedLanguage = (Locale? locale) {
      setState(() {});
    };

    // if (PlatformTool.isIOS() || PlatformTool.isAndroid()) {
    //   registerWxApi(
    //     appId: weixinAppId,
    //     universalLink: universalLink,
    //   );
    // }

    // weChatResponseEventHandler.listen((event) {
    //   print("=====================");
    //   print("errorCode: ${event.errCode}");
    //   print("errorMessage: ${event.errStr}");
    //   if (event is WeChatShareResponse) {
    //     print("type: ${event.type}");
    //     print("success:${event.isSuccessful}");
    //   }
    //   showSuccessMessage('分享成功', duration: const Duration(seconds: 3));
    // });
    super.initState();
  }


  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MultiRepositoryProvider(
      providers: [
        RepositoryProvider<ChatMessageRepository>(
            create: (context) => widget.chatMsgRepo),
        RepositoryProvider<OpenAIRepository>(
            create: (context) => widget.openAIRepo),
        RepositoryProvider<SettingRepository>(
            create: (context) => widget.settingRepo),
        RepositoryProvider<CacheRepository>(
            create: (context) => widget.cacheRepo),
      ],
      child: ChangeNotifierProvider(
          create: (context) => AppTheme.instance
            ..mode = AppTheme.themeModeFormString(
                widget.settingRepo.stringDefault(settingThemeMode, 'dark')),
          builder: (context, _) {
            final appTheme = context.watch<AppTheme>();
            return ScreenUtilInit(
              // 设计尺寸
              designSize: const Size(375, 667),
              // 是否根据最小宽度和高度调整文本
              minTextAdapt: true,
              builder: (context, child) {
                return MaterialApp.router(
                  title: 'ChatGreat-sy',
                  // themeMode: appTheme.mode,
                  theme: createDarkThemeData(),
                  // darkTheme: createDarkThemeData(),
                  debugShowCheckedModeBanner: false,
                  builder: (context, child) {
                    // 这里设置了全局字体固定大小，不随系统设置变更
                    // TODO 后面要增加一个设置项，允许用户自定义字体大小
                    return FlutterEasyLoading(
                      child: MediaQuery(
                        data:
                            MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
                        child: BotToastInit()(context, child),
                      ),
                    );
                  },
                  routerConfig: widget._router,
                  supportedLocales: widget.localization.supportedLocales,
                  localizationsDelegates: [
                    ...widget.localization.localizationsDelegates,
                    RefreshLocalizations.delegate,
                  ],
                  scrollBehavior:
                      PlatformTool.isAndroid() || PlatformTool.isIOS()
                          ? null
                          : const MaterialScrollBehavior().copyWith(
                              dragDevices: {
                                PointerDeviceKind.touch,
                                PointerDeviceKind.mouse,
                                PointerDeviceKind.stylus,
                                PointerDeviceKind.trackpad,
                              },
                            ),
                );
              },
            );
          }),
    );
  }
}

ThemeData createLightThemeData() {
  return ThemeData.light().copyWith(
    extensions: [CustomColors.light],
    useMaterial3: true,
    appBarTheme: const AppBarTheme(
      // backgroundColor: Color.fromARGB(255, 250, 250, 250),
      backgroundColor: Colors.transparent,
      scrolledUnderElevation: 0,
    ),
    iconButtonTheme: PlatformTool.isMacOS()
        ? IconButtonThemeData(
            style: ButtonStyle(
              overlayColor: MaterialStateProperty.all(Colors.transparent),
            ),
          )
        : null,
    dividerColor: Colors.transparent,
    dialogBackgroundColor: Colors.white,
    dialogTheme: DialogTheme(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(10),
      ),
      elevation: 0,
    ),
    textButtonTheme: TextButtonThemeData(
      style: TextButton.styleFrom(
        foregroundColor: const Color.fromARGB(
            255, 9, 185, 85), // This is a custom color variable
      ),
    ),
  );
}

ThemeData createDarkThemeData() {
  return ThemeData.dark().copyWith(
    extensions: [CustomColors.dark],
    useMaterial3: true,
    appBarTheme: const AppBarTheme(
      // backgroundColor: Color.fromARGB(255, 48, 48, 48),
      backgroundColor: Colors.transparent,
      scrolledUnderElevation: 0,
    ),
    iconButtonTheme: PlatformTool.isMacOS()
        ? IconButtonThemeData(
            style: ButtonStyle(
              overlayColor: MaterialStateProperty.all(Colors.transparent),
            ),
          )
        : null,
    dividerColor: Colors.transparent,
    dialogBackgroundColor: const Color.fromARGB(255, 48, 48, 48),
    dialogTheme: DialogTheme(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(10),
      ),
      elevation: 0,
    ),
    textButtonTheme: TextButtonThemeData(
      style: TextButton.styleFrom(
        foregroundColor: const Color.fromARGB(
            255, 9, 185, 85), // This is a custom color variable
      ),
    ),
  );
}
